package cn.turboinfo.fuyang.api.domain.common.handler.rule;

import cn.turboinfo.fuyang.api.entity.common.enumeration.rule.RuleControlType;
import cn.turboinfo.fuyang.api.entity.common.pojo.rule.RuleGroup;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;

@Slf4j
@Component
public class RuleGroupFilterFactory {

    private final Map<RuleControlType, IRuleGroupFilter> filterMap;

    public RuleGroupFilterFactory(@Autowired List<IRuleGroupFilter> filterList) {
        if (filterList == null) {
            filterMap = Collections.unmodifiableMap(new HashMap<>());
        } else {
            filterMap = Collections.unmodifiableMap(
                    filterList
                            .stream()
                            .collect(
                                    Collectors.toMap(IRuleGroupFilter::getType, Function.identity())
                            )
            );
        }
    }

    public Optional<IRuleGroupFilter> getFilter(RuleControlType controlType) {
        return Optional.ofNullable(filterMap.get(controlType));
    }

    /**
     * 按照规则组对单个对象进行过滤
     *
     * @param ruleGroup     规则组定义
     * @param controlObject 规则组对应的控制对象
     */
    public Object filterObject(Object element, RuleGroup ruleGroup, Object controlObject) {
        Optional<IRuleGroupFilter> filterOptional = getFilter(ruleGroup.getControlType());
        if (filterOptional.isEmpty()) {
            log.info("未找到规则过滤器, 不作过滤直接返回, type={}", ruleGroup.getControlType());
            return element;
        }
        IRuleGroupFilter filter = filterOptional.get();
        if (filter instanceof IRuleGroupObjectFilter) {
            return ((IRuleGroupObjectFilter) filter).filterObject(element, ruleGroup, controlObject);
        } else {
            log.info("找到规则过滤器, 但对应规则引擎不支持集合过滤, 不作过滤直接返回, type={}", ruleGroup.getControlType());
            return element;
        }
    }

    /**
     * 按照规则组对集合对象进行过滤
     *
     * @param elementList   要过滤的集合
     * @param ruleGroup     规则组定义
     * @param controlObject 规则组对应的控制对象
     * @param <T>
     * @return
     */
    public <T> List<T> filterCollection(List<T> elementList, RuleGroup ruleGroup, Object controlObject) {
        Optional<IRuleGroupFilter> filterOptional = getFilter(ruleGroup.getControlType());
        if (filterOptional.isEmpty()) {
            log.info("未找到规则过滤器, 不作过滤直接返回, type={}", ruleGroup.getControlType());
            return elementList;
        }
        IRuleGroupFilter filter = filterOptional.get();
        if (filter instanceof IRuleGroupCollectionFilter) {
            return ((IRuleGroupCollectionFilter) filter).filterCollection(elementList, ruleGroup, controlObject);
        } else {
            log.info("找到规则过滤器, 但对应规则引擎不支持集合过滤, 不作过滤直接返回, type={}", ruleGroup.getControlType());
            return elementList;
        }
    }

}
